The Unshrinking and Unreducing C source code of Samuel H. Smith was used in UnZip 2.0. The full version 1.2 of Samuel H. Smith’s code from the file ST_UNZIP.ZIP follows:

#define ATARI_ST 1

/*
 * Copyright 1989 Samuel H. Smith;  All rights reserved
 *
 * Do not distribute modified versions without my permission.
 * Do not remove or alter this notice or any other copyright notice.
 * If you use this in your own program you must distribute source code.
 * Do not use any of this in a commercial product.
 *
 */

/*
 * UnZip - A simple zipfile extract utility
 *
 * To compile:
 *      tcc -B -O -Z -G -mc unzip.c        ;turbo C 2.0, compact model
 *
 */

#define CODE_VERSION  "UnZip:  Zipfile Extract v1.2 of 03-15-89;  (C) 1989 Samuel H. Smith"
#define PRG_VERSION   "\
UnZip:  Atari ST Zipfile Extract v1.2 of 03-30-89\n\
Ported to the Atari ST by Darin Wayrynen.\n\
Derived from code Copyrighted (c)1989 by S.H.Smith"

typedef unsigned char byte;
/* code assumes UNSIGNED bytes */
typedef long longint;
typedef unsigned word;
typedef char boolean;

#define STRSIZ 256

#include <stdio.h>
 /* this is your standard header for all C compiles */

#ifndef ATARI_ST
#include <stdlib.h>
 /* this include defines various standard library prototypes */
#else
long buffer_size,in_size,out_size;
#endif

/*
 * SEE HOST OPERATING SYSTEM SPECIFICS SECTION STARTING NEAR LINE 180
 *
 */

/* ----------------------------------------------------------- */
/*
 * Zipfile layout declarations
 *
 */

typedef longint signature_type;

#define LOCAL_FILE_HEADER_SIGNATURE  0x04034b50L

typedef struct local_file_header 

word version_needed_to_extract;

word general_purpose_bit_flag;

word compression_method;

word last_mod_file_time;

word last_mod_file_date;

longint crc32;

longint compressed_size;

longint uncompressed_size;

word filename_length;

word extra_field_length;
 local_file_header;

#define CENTRAL_FILE_HEADER_SIGNATURE  0x02014b50L

typedef struct central_directory_file_header 

word version_made_by;

word version_needed_to_extract;

word general_purpose_bit_flag;

word compression_method;

word last_mod_file_time;

word last_mod_file_date;

longint crc32;

longint compressed_size;

longint uncompressed_size;

word filename_length;

word extra_field_length;

word file_comment_length;

word disk_number_start;

word internal_file_attributes;

longint external_file_attributes;

longint relative_offset_local_header;
 central_directory_file_header;

#define END_CENTRAL_DIR_SIGNATURE  0x06054b50L

typedef struct end_central_dir_record 

word number_this_disk;

word number_disk_with_start_central_directory;

word total_entries_central_dir_on_this_disk;

word total_entries_central_dir;

longint size_central_directory;

longint offset_start_central_directory;

word zipfile_comment_length;
 end_central_dir_record;

/* ----------------------------------------------------------- */
/*
 * input file variables
 *
 */

#define INBUFSIZ 0x2000L
byte *inbuf;

/* input file buffer - any size is legal */
byte *inptr;

int incnt;
unsigned bitbuf;
int bits_left;
boolean zipeof;

int zipfd;
char zipfn[STRSIZ];
local_file_header lrec;

/* ----------------------------------------------------------- */
/*
 * output stream variables
 *
 */

#define OUTBUFSIZ 0x6000L
byte *outbuf;                   /* buffer for rle look-back */
byte *outptr;

longint outpos;

/* absolute position in outfile */
int outcnt;

/* current position in outbuf */

int outfd;
char filename[STRSIZ];
char extra[STRSIZ];

#define DLE 144

/* ----------------------------------------------------------- */
/*
 * shrink/reduce working storage
 *
 */

int factor;
byte followers[256][64];
byte Slen[256];

#define max_bits 13
#define init_bits 9
#define hsize 8192
#define first_ent 257
#define clear 256

typedef int hsize_array_integer[hsize+1];
typedef byte hsize_array_byte[hsize+1];

hsize_array_integer prefix_of;
hsize_array_byte suffix_of;
hsize_array_byte stack;

int codesize;
int maxcode;
int free_ent;
int maxcodemax;
int offset;
int sizex;

/* ============================================================= */
/*
 * Host operating system details
 *
 */

#ifndef ATARI_ST
#include <string.h>
#else
#include <strings.h>
#define strchr index
#endif
 /* this include defines strcpy, strcmp, etc. */

#ifndef ATARI_ST
#include <io.h>
 /*
  * this include file defines
  *             struct ftime ...        (* file time/date stamp info *)
  *             int setftime (int handle, struct ftime *ftimep);
  *             #define SEEK_CUR  1     (* lseek() modes *)
  *             #define SEEK_END  2
  *             #define SEEK_SET  0
  */
#else
#define SEEK_CUR  1     (* lseek() modes *)
#define SEEK_END  2
#define SEEK_SET  0
#endif

#include <fcntl.h>
 /*
  * this include file defines
  *             #define O_BINARY 0x8000  (* no cr-lf translation *)
  * as used in the open() standard function
  */

#ifndef ATARI_ST
#include <sys/stat.h>
 /*
  * this include file defines
  *             #define S_IREAD 0x0100  (* owner may read *)
  *             #define S_IWRITE 0x0080 (* owner may write *)
  * as used in the creat() standard function
  */
#endif

#ifdef ATARI_ST
#define HIGH_LOW 1
#include <osbind.h>
typedef struct _dt                     /* My creation! DAW */

unsigned realdate;

unsigned realtime;
 dt;
#endif

 /*
  * change 'undef' to 'define' if your machine stores high order bytes in
  * lower addresses.
  */

#ifndef ATARI_ST
void set_file_time()
 /*
  * set the output file date/time stamp according to information from the
  * zipfile directory record for this file 
  */

union 
                dt ft;        /* system file time record */

struct 
                        word ztime;     /* date and time words */
                        word zdate;     /* .. same format as in .ZIP file */

 zt;

 td;

/*

 * set output file date and time - this is optional and can be

 * deleted if your compiler does not easily support setftime() 

 */

td.zt.ztime = lrec.last_mod_file_time;

td.zt.zdate = lrec.last_mod_file_date;

setftime(outfd, &td.ft);

#else
#define set_file_time() ;
#endif

int create_output_file()
 /* return non-0 if creat failed */

/* create the output file with READ and WRITE permissions */
#ifndef ATARI_ST

outfd = creat(filename, S_IWRITE | S_IREAD);
#else

outfd = open(filename, O_CREAT | O_RDWR| O_BINARY);
#endif

if (outfd < 1) 

printf("Can't create output: %s\n", filename);

return 1;

/*

 * close the newly created file and reopen it in BINARY mode to

 * disable all CR/LF translations 

 */
#ifndef ATARI_ST

/*

 * Not neccessary with Atari ST.  Just open() in Binary mode.

 */

close(outfd);

outfd = open(filename, O_RDWR | O_BINARY);
#endif

/* write a single byte at EOF to pre-allocate the file */
        lseek(outfd, lrec.uncompressed_size - 1L, SEEK_SET);

write(outfd, "?", 1);

lseek(outfd, 0L, SEEK_SET);

return 0;

int open_input_file()
 /* return non-0 if creat failed */

/*

 * open the zipfile for reading and in BINARY mode to prevent cr/lf

 * translation, which would corrupt the bitstreams 

 */

zipfd = open(zipfn, O_RDONLY | O_BINARY);

if (zipfd < 1) 

printf("Can't open input file: %s\n", zipfn);

return (1);

return 0;

#ifdef HIGH_LOW

void swap_bytes(wordp)
word *wordp;
 /* convert intel style 'short int' variable to host format */

char *charp = (char *) wordp;

char temp;

temp = charp[0];

charp[0] = charp[1];

charp[1] = temp;

void swap_lbytes(longp)
longint *longp;
 /* convert intel style 'long' variable to host format */

char *charp = (char *) longp;

char temp[4];

temp[3] = charp[0];

temp[2] = charp[1];

temp[1] = charp[2];

temp[0] = charp[3];

charp[0] = temp[0];

charp[1] = temp[1];

charp[2] = temp[2];

charp[3] = temp[3];

#endif

/* ============================================================= */

int FillBuffer()
 /* fill input buffer if possible */

int readsize;

        if (lrec.compressed_size <= 0)

return incnt = 0;

        if (lrec.compressed_size > in_size)

readsize = in_size;

else
                readsize = (int) lrec.compressed_size;

incnt = read(zipfd, inbuf, readsize);

        lrec.compressed_size -= incnt;

inptr = inbuf;

return incnt--;

int ReadByte(x)
unsigned *x;
 /* read a byte; return 8 if byte available, 0 if not */

if (incnt-- == 0)

if (FillBuffer() == 0)

return 0;

*x = *inptr++;

return 8;

/* ------------------------------------------------------------- */
static unsigned mask_bits[] =
        0,     0x0001, 0x0003, 0x0007, 0x000f,
                0x001f, 0x003f, 0x007f, 0x00ff,
                0x01ff, 0x03ff, 0x07ff, 0x0fff,
                0x1fff, 0x3fff, 0x7fff, 0xffff
        ;

int FillBitBuffer(bits)
register int bits;

/* get the bits that are left and read the next word */

unsigned temp;
        register int result = bitbuf;

int sbits = bits_left;

bits -= bits_left;

/* read next word of input */

bits_left = ReadByte(&bitbuf);

bits_left += ReadByte(&temp);

bitbuf |= (temp << 8);

if (bits_left == 0)

zipeof = 1;

/* get the remaining bits */
        result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
        bitbuf >>= bits;
        bits_left -= bits;
        return result;

#define READBIT(nbits,zdest)  if (nbits <= bits_left)  zdest = (int)(bitbuf & mask_bits[nbits]); bitbuf >>= nbits; bits_left -= nbits;  else zdest = FillBitBuffer(nbits);

/*
 * macro READBIT(nbits,zdest)
 *  
 *      if (nbits <= bits_left) 
 *          zdest = (int)(bitbuf & mask_bits[nbits]);
 *          bitbuf >>= nbits;
 *          bits_left -= nbits;
 *       else
 *          zdest = FillBitBuffer(nbits);
 *  
 *
 */

/* ------------------------------------------------------------- */

#include "crc32.h"

/* ------------------------------------------------------------- */

void FlushOutput()
 /* flush contents of output buffer */

UpdateCRC(outbuf, outcnt);

write(outfd, outbuf, outcnt);

outpos += outcnt;

outcnt = 0;

outptr = outbuf;

#define OUTB(intc)  *outptr++=intc; if (++outcnt==out_size) FlushOutput(); 

/*
 *  macro OUTB(intc)
 *  
 *      *outptr++=intc;
 *      if (++outcnt==out_size)
 *          FlushOutput();
 *  
 *
 */

/* ----------------------------------------------------------- */

void LoadFollowers()

        register int x;
        register int i;

for (x = 255; x >= 0; x--) 
                READBIT(6,Slen[x]);

for (i = 0; i < Slen[x]; i++) 
                        READBIT(8,followers[x][i]);

/* ----------------------------------------------------------- */
/*
 * The Reducing algorithm is actually a combination of two
 * distinct algorithms.  The first algorithm compresses repeated
 * byte sequences, and the second algorithm takes the compressed
 * stream from the first algorithm and applies a probabilistic
 * compression method.
 */

int L_table[] = 0, 0x7f, 0x3f, 0x1f, 0x0f;

int D_shift[] = 0, 0x07, 0x06, 0x05, 0x04;
int D_mask[]  = 0, 0x01, 0x03, 0x07, 0x0f;

int B_table[] = 8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,

 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,

 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,

 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,

 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,

 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,

 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,

 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

 8, 8, 8, 8;

/* ----------------------------------------------------------- */

void unReduce()
 /* expand probablisticly reduced data */

        register int lchar;
        register int nchar;
        int ExState;
        register int V;
        register int Len;

        factor = lrec.compression_method - 1;

ExState = 0;

lchar = 0;

LoadFollowers();

        while (((outpos + outcnt) < lrec.uncompressed_size) && (!zipeof)) 

if (Slen[lchar] == 0)
                        READBIT(8,nchar)      /* ; */
                else

                        READBIT(1,nchar);
                        if (nchar != 0)
                                READBIT(8,nchar)      /* ; */
                        else

                                int follower;
                                int bitsneeded = B_table[Slen[lchar]];
                                READBIT(bitsneeded,follower);
                                nchar = followers[lchar][follower];

/* expand the resulting byte */

switch (ExState) 

case 0:
                        if (nchar != DLE)
                                OUTB(nchar) /*;*/

else

ExState = 1;

break;

case 1:
                        if (nchar != 0) 
                                V = nchar;

Len = V & L_table[factor];

if (Len == L_table[factor])

ExState = 2;

else

ExState = 3;

else 
                                OUTB(DLE);

ExState = 0;

break;

                case 2: 
                                Len += nchar;

ExState = 3;

break;

                case 3: 

register int i = Len + 3;

int offset = (((V >> D_shift[factor]) &
                                          D_mask[factor]) << 8) + nchar + 1;

longint op = outpos + outcnt - offset;

/* special case- before start of file */

while ((op < 0L) && (i > 0)) 

OUTB(0);

op++;

i--;

/* normal copy of data from output buffer */

register int ix = (int) (op % out_size);

                                        /* do a block memory copy if possible */
                                        if ( ((ix    +i) < out_size) &&
                                             ((outcnt+i) < out_size) ) 
                                                memcpy(outptr,&outbuf[ix],i);
                                                outptr += i;
                                                outcnt += i;

                                        /* otherwise copy byte by byte */
                                        else while (i--) 
                                                OUTB(outbuf[ix]);
                                                if (++ix >= out_size)
                                                        ix = 0;

ExState = 0;

break;

                /* store character for next iteration */
                lchar = nchar;

/* ------------------------------------------------------------- */
/*
 * Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
 * with partial clearing.
 *
 */

void partial_clear()

        register int pr;
        register int cd;

/* mark all nodes as potentially unused */

for (cd = first_ent; cd < free_ent; cd++)

prefix_of[cd] |= 0x8000;

/* unmark those that are used by other nodes */

for (cd = first_ent; cd < free_ent; cd++) 

pr = prefix_of[cd] & 0x7fff;
/* reference to another node? */
                if (pr >= first_ent)            /* flag node as referenced */

prefix_of[pr] &= 0x7fff;

/* clear the ones that are still marked */

for (cd = first_ent; cd < free_ent; cd++)

if ((prefix_of[cd] & 0x8000) != 0)

prefix_of[cd] = -1;

/* find first cleared node as next free_ent */
        cd = first_ent;
        while ((cd < maxcodemax) && (prefix_of[cd] != -1))
                cd++;
        free_ent = cd;

/* ------------------------------------------------------------- */

void unShrink()

        #define  GetCode(dest) READBIT(codesize,dest)

register int code;

register int stackp;

int finchar;

int oldcode;

int incode;

/* decompress the file */

maxcodemax = 1 << max_bits;

codesize = init_bits;

maxcode = (1 << codesize) - 1;

free_ent = first_ent;

offset = 0;

sizex = 0;

for (code = maxcodemax; code > 255; code--)

prefix_of[code] = -1;

for (code = 255; code >= 0; code--) 

prefix_of[code] = 0;

suffix_of[code] = code;

GetCode(oldcode);

if (zipeof)

return;

finchar = oldcode;

        OUTB(finchar);

        stackp = hsize;

while (!zipeof) 

GetCode(code);

if (zipeof)

return;

while (code == clear) 

GetCode(code);

switch (code) 

case 1:

codesize++;

if (codesize == max_bits)

maxcode = maxcodemax;

else

maxcode = (1 << codesize) - 1;

break;

case 2:

partial_clear();

break;

GetCode(code);

if (zipeof)

return;

/* special case for KwKwK string */

incode = code;

if (prefix_of[code] == -1) 
                        stack[--stackp] = finchar;

code = oldcode;

/* generate output characters in reverse order */

while (code >= first_ent) 
                        stack[--stackp] = suffix_of[code];

code = prefix_of[code];

finchar = suffix_of[code];
                stack[--stackp] = finchar;

                /* and put them out in forward order, block copy */
                if ((hsize-stackp+outcnt) < out_size) 
                        memcpy(outptr,&stack[stackp],hsize-stackp);
                        outptr += hsize-stackp;
                        outcnt += hsize-stackp;
                        stackp = hsize;

                /* output byte by byte if we can't go by blocks */
                else while (stackp < hsize)
                        OUTB(stack[stackp++]);

/* generate new entry */

code = free_ent;

if (code < maxcodemax) 

prefix_of[code] = oldcode;

suffix_of[code] = finchar;

do

code++;

while ((code < maxcodemax) && (prefix_of[code] != -1));

free_ent = code;

/* remember previous code */

oldcode = incode;

/* ---------------------------------------------------------- */

void extract_member()

unsigned b;

bits_left = 0;

bitbuf = 0;

incnt = 0;

outpos = 0L;

outcnt = 0;

outptr = outbuf;

zipeof = 0;

crc32val = 0xFFFFFFFFL;

/* create the output file with READ and WRITE permissions */

if (create_output_file())

prg_exit(1);

        switch (lrec.compression_method) 

case 0:

/* stored */

printf(" Extracting: %-12s ", filename);

while (ReadByte(&b))

OUTB(b);

break;

        case 1: 

printf("UnShrinking: %-12s ", filename);

unShrink();

break;

case 2:

case 3:

case 4:
        case 5: 

printf("  Expanding: %-12s ", filename);

unReduce();

break;

default:

printf("Unknown compression method.");

/* write the last partial buffer, if any */

if (outcnt > 0) 

UpdateCRC(outbuf, outcnt);

write(outfd, outbuf, outcnt);

/* set output file date and time */

set_file_time();

close(outfd);

crc32val = -1 - crc32val;
#ifdef HIGH_LOW

swap_lbytes(&lrec.crc32);
#endif
        if (crc32val != lrec.crc32)
                printf(" Bad CRC %08lx  (should be %08lx)", lrec.crc32, crc32val);

printf("\n");

/* ---------------------------------------------------------- */

void get_string(len,s)
int len;
char *s;

read(zipfd, s, len);

s[len] = 0;

/* ---------------------------------------------------------- */

void process_local_file_header()

read(zipfd, &lrec, sizeof(lrec));

#ifdef HIGH_LOW

swap_bytes(&lrec.filename_length);

swap_bytes(&lrec.extra_field_length);

swap_lbytes(&lrec.compressed_size);

swap_lbytes(&lrec.uncompressed_size);

swap_bytes(&lrec.compression_method);
#endif

get_string(lrec.filename_length, filename);

get_string(lrec.extra_field_length, extra);

extract_member();

/* ---------------------------------------------------------- */

void process_central_file_header()

central_directory_file_header rec;

char filename[STRSIZ];

char extra[STRSIZ];

char comment[STRSIZ];

read(zipfd, &rec, sizeof(rec));

#ifdef HIGH_LOW

swap_bytes(&rec.filename_length);

swap_bytes(&rec.extra_field_length);

swap_bytes(&rec.file_comment_length);
#endif

    get_string(rec.filename_length, filename);

get_string(rec.extra_field_length, extra);

get_string(rec.file_comment_length, comment);

/* ---------------------------------------------------------- */

void process_end_central_dir()

end_central_dir_record rec;

char comment[STRSIZ];

read(zipfd, &rec, sizeof(rec));

#ifdef HIGH_LOW

swap_bytes(&rec.zipfile_comment_length);
#endif

get_string(rec.zipfile_comment_length, comment);

/* ---------------------------------------------------------- */

void process_headers()

longint sig;

while (1) 

if (read(zipfd, &sig, sizeof(sig)) != sizeof(sig))

return;

#ifdef HIGH_LOW

swap_lbytes(&sig);
#endif

                if (sig == LOCAL_FILE_HEADER_SIGNATURE)

process_local_file_header();
                else if (sig == CENTRAL_FILE_HEADER_SIGNATURE)

process_central_file_header();
                else if (sig == END_CENTRAL_DIR_SIGNATURE) 

process_end_central_dir();

return;

                else 

printf("Invalid Zipfile Header\n");

return;

/* ---------------------------------------------------------- */

void extract_zipfile()

/*

 * open the zipfile for reading and in BINARY mode to prevent cr/lf

 * translation, which would corrupt the bitstreams 

 */

printf("Buffers - ");

printf("(input --> %7ld bytes) ",in_size);

printf("(output --> %7ld bytes)\n\n",out_size);

if (open_input_file())

prg_exit(1);

process_headers();

close(zipfd);

/* ---------------------------------------------------------- */
/*
 * main program
 *
 */

void main(argc,argv)
int argc;
char **argv;

#ifdef ATARI_ST

int buffer_fail = 0;
#endif

   
printf("\n\n%s\n",PRG_VERSION); 

printf("Courtesy of:  Darin Wayrynen, S.H.Smith and\n              The Tool Shop BBS,  (602) 279-2673.\n"); 

if (argc != 2)

printf("\nYou may copy and distribute this program freely, provided that:\n");

printf("    1)   No fee is charged for such copying and distribution, and\n");

printf("    2)   It is distributed ONLY in its original, unmodified state.\n\n");

printf("If you wish to distribute a modified version of this program, you MUST\n");

printf("include the source code.\n\n");

printf("If you modify this program, we would appreciate a copy of the  new source\n");

printf("code.  Samuel is holding the copyright on the source code, so please don't\n");

printf("delete his  name from the program files or from the documentation.\n\n");
        printf("IN NO EVENT WILL WE BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY LOST\n");
        printf("PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES\n");
        printf("ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR FOR ANY\n");
        printf("CLAIM BY ANY OTHER PARTY.\n\n");
        printf("Usage:  UnZip FILE[.zip]\n");
#ifdef ATARI_ST

prg_exit(0);
#else
        exit(1);
#endif

printf("\n");

/* .ZIP default if none provided by user */

strcpy(zipfn, argv[1]);

if (strchr(zipfn, '.') == NULL)

strcat(zipfn, ".ZIP");

#ifdef ATARI_ST

/* ST buffer allocation */

buffer_size = Malloc(-1L)-10000L;              /* returns largest free block */

if (buffer_size<(INBUFSIZ + OUTBUFSIZ))

buffer_fail=1;

in_size = (buffer_size-(INBUFSIZ + OUTBUFSIZ))/100L*55L+INBUFSIZ;

out_size = (buffer_size-(INBUFSIZ + OUTBUFSIZ))/100L*35L+OUTBUFSIZ;

inbuf = (byte *)Malloc(in_size); 

/* 60% */

outbuf = (byte *)Malloc(out_size);

/* 40% */

if ((inbuf== NULL) || (outbuf == NULL) || buffer_fail)

printf("Can't allocate buffers!\n");

prg_exit(1);

#else
        /* allocate i/o buffers */

inbuf = (byte *) (malloc(INBUFSIZ));

outbuf = (byte *) (malloc(OUTBUFSIZ));

if ((inbuf == NULL) || (outbuf == NULL)) 

printf("Can't allocate buffers!\n");

exit(1);

#endif
        /* do the job... */
        extract_zipfile();
#ifdef ATARI_ST

prg_exit(0);
#else

exit(0);
#endif

prg_exit(value)
int value;

setbuffer(stdout,0L);

 
/* turn off printf

   buffering */

printf("\nPress any key to continue.");

Bconin(2);

/* wait for keypress before

                                               exiting, in case prg is

                                               run from desktop */

printf("\n");

exit(value);

#ifdef ATARI_ST
memcpy(to,from,count)
register char *to,*from;
register unsigned int count;

for(;count>0;--count,++to,++from)

*to=*from;

#endif